﻿using System;
using System.Collections.Generic;
using System.Linq;
using Shell.Common;
using Shell.KnowledgeBase;
using Shell.Nodes;

namespace Shell
{
    public static class Program
    {
        static void Main(string[] args)
        {
            var kb = new Base();
            kb.LoadFromXml("apriori.xml");

            var context = new List<Statement>();

            var predefinedInput = new List<string>
                {
                    "Is clu human ?"
                };

            while (true)
            {
                Console.Write("-:");

                var searcher = new Searcher();

                var originalInputString = GetUserInput(predefinedInput);
                var originalInput = originalInputString.ToStatementLetterwise(new Dictionary<string, Variable>());

                var searchRoot = new SyntaxReductionNode(
                    originalInput,
                    kb.SyntaxRules,
                    _ => new TransactionMatchNode(
                             _,
                             kb.Transactions,
                             (transaction, index, bindingContext) =>
                             new OnthologyMatchNode(
                                 transaction.Statements,
                                 bindingContext,
                                 kb.Statements,
                                 kb.Implications,
                                 (bindingContext1) => 
                                     new ContextMatchNode(
                                         transaction, 
                                         index, 
                                         bindingContext1,
                                         context,
                                         (statementToExpand, bindingContext3) => 
                                             new SyntaxExpansionNode(
                                                 statementToExpand, 
                                                 kb.SyntaxRules,
                                                 result => new ResultNode<Statement>(result))))));

                var searchResultSet = searcher.Search<ResultNode<Statement>>(searchRoot).ToArray();
                var selectedOutput = searchResultSet.First().Value;


                Console.WriteLine(selectedOutput.ToString().Trim());

                context.Add(originalInput);
                context.Add(selectedOutput);
            }
        }

        private static Statement ConstructReplyForUnknownInput()
        {
            return new Statement("no-answer".CreateAtomicStatement().Yield());
        }

        private static string GetUserInput(IList<string> predefinedInput)
        {
            string originalInputString;
            if (predefinedInput.Count > 0)
            {
                Console.WriteLine(predefinedInput[0]);
                originalInputString = predefinedInput[0];
                predefinedInput.RemoveAt(0);
            }
            else
            {
                originalInputString = Console.ReadLine();
            }
            return originalInputString;
        }
    }
}
